package com.zf.museum.shiro;

import com.zf.museum.model.Administrator;
import com.zf.museum.model.Role;
import com.zf.museum.repository.AdministratorRepository;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

@Component
public class AdminRealm extends AuthorizingRealm {

    @Autowired
    private AdministratorRepository administratorRepository;

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {

        SimpleAuthorizationInfo info = null;
        // 获取当前登录类型
        String loginType = (String) SecurityUtils.getSubject().getSession().getAttribute("loginType");

        if (LoginType.ADMIN.toString().equals(loginType)) {
            String account = (String) principalCollection.getPrimaryPrincipal();
            Administrator admin= administratorRepository.getAdministratorByAccount(account);
            List<Role> roles = admin.getRoles();
            Set<String> set = new HashSet<>();
            for (Role role: roles
                 ) {
                set.add(role.getRole());
            }

            info = new SimpleAuthorizationInfo(set);
        }
        return info;
    }

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {

        Administrator admin = null;
        /*把AuthenticationToken转换为CustomizedToken*/
        CustomizedToken customizedToken = (CustomizedToken) authenticationToken;
        /*从CustomizedToken中获取account*/
        String account = customizedToken.getUsername();
        /*获取用户信息*/
        admin = administratorRepository.getAdministratorByAccount(account);
        System.out.println("数据库取出的密码："+admin.getPassword());
        if (admin == null) {
            throw new UnknownAccountException("用户不存在");
        }
         /*根据用户的情况，来构建AuthenticationInfo对象并返回，通常使用的实现类为SimpleAuthenticationInfo
        以下信息从数据库中获取
        （1）principal：认证的实体信息，可以是email，也可以是数据表对应的用户的实体类对象*/
         Object principal = account;
         /*（2）credentials：密码*/
         Object credentials = admin.getPassword();
         /*（3）realmName：当前realm对象的name，调用父类的getName()方法即可*/
         String realmName = getName();
         /*（4）盐值：取用户信息中唯一的字段来生成盐值，避免由于两个用户原始密码相同，加密后的密码也相同*/
        ByteSource credentialsSalt = ByteSource.Util.bytes(account);
        SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(principal, credentials, credentialsSalt,
                realmName);
        return info;
    }
}
